package com.xiaobaibai.security.login.config;

import com.xiaobaibai.security.common.HttpFailureHandler;
import com.xiaobaibai.security.login.dao.LoginUserDetailService;
import com.xiaobaibai.security.login.filter.MyUsernamePasswordAuthenticationFilter;
import com.xiaobaibai.security.login.filter.MyUsernamePasswordAuthenticationFilter;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.DefaultSecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

//@Configuration
public class No2LoginConfig extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {

    /**
     * 实验1SecurityConfigurerAdapter关系  实验2 重写UsernamePassword
     * AbstractHttpConfigurer和SecurityConfigurerAdapter关系
     * 解惑:
     * 1.AbstractHttpConfigurer的父类就是SecurityConfigurerAdapter
     * 2.它们的第一个泛型都是DefaultSecurityFilterChain,关键在于第二个泛型的不同
     *   前者是HttpSecurityBuilder->SecurityBuilder,
     *   后者是HttpSecurity->(HttpSecurityBuilder->SecurityBuilder,SecurityBuilder)
     *   后者就是比前者多了一个HttpSecurity,而前者HttpSecurityBuilder接口方法的实现类又是HttpSecurity
     *
     *   总之所以对于我这种小白来说,两者没有区别,反而推荐用继承SecurityConfigurerAdapter(更方便)
     *
     *
     */

    private MyUsernamePasswordAuthenticationFilter myUsernamePasswordAuthenticationFilter;

    private LoginUserDetailService userDetailService;

    private PasswordEncoder passwordEncoder;

    public No2LoginConfig(){
        myUsernamePasswordAuthenticationFilter=new MyUsernamePasswordAuthenticationFilter();
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        //设置Filter使用的AuthenticationManager,这里取公共的即可
        myUsernamePasswordAuthenticationFilter
                .setAuthenticationManager(http.getSharedObject(AuthenticationManager.class));
        myUsernamePasswordAuthenticationFilter
                .setAuthenticationFailureHandler(new HttpFailureHandler());

        //未知操作
        MyUsernamePasswordAuthenticationFilter filter =
                postProcess(this.myUsernamePasswordAuthenticationFilter);

        DaoAuthenticationProvider daoProvider = new DaoAuthenticationProvider();
        daoProvider.setUserDetailsService(userDetailService);
        daoProvider.setPasswordEncoder(passwordEncoder);


        //在LogoutFilter后面加上
        http.authenticationProvider(daoProvider)
                .addFilterAfter(filter, UsernamePasswordAuthenticationFilter.class);
    }

    public No2LoginConfig loginSuccessHandler(AuthenticationSuccessHandler authSuccessHandler){
        myUsernamePasswordAuthenticationFilter.setAuthenticationSuccessHandler(authSuccessHandler);
        return this;
    }

    public No2LoginConfig setUserDetailService(LoginUserDetailService userDetailService) {
        this.userDetailService = userDetailService;
        return this;
    }

    public No2LoginConfig setPasswordEncoder(PasswordEncoder passwordEncoder) {
        this.passwordEncoder = passwordEncoder;
        return this;
    }
}
